package opt

import "molydb/cache"

var (
	DefaultBlockCacher = LRUCacher
)

var (
	//
	LRUCacher = CacherFunc(cache.NewLRU)
	//
	NoCacher = CacherFunc(nil)
)

const (
	StrictMainfest Strict = 1 << iota

	StrictJournalChecksum

	StrictJournal

	StrictBlockChecksum
	StrictCompaction
	StrictReader
	StrictRecovery
	StrictOverride
	StrictAll     = StrictMainfest | StrictJournalChecksum | StrictJournal | StrictBlockChecksum | StrictCompaction | StrictReader | StrictRecovery
	DefaultStrict = StrictJournalChecksum | StrictBlockChecksum | StrictCompaction | StrictReader
	NoStrict      = ^StrictAll
)

type cacherFunc struct {
	NewFunc func(capacity int) cache.Cacher
}

func (c *cacherFunc) New(capacity int) cache.Cacher {
	if c != nil && c.NewFunc != nil {
		return c.NewFunc(capacity)
	}
	return nil
}

func CacherFunc(f func(capacity int) cache.Cacher) Cacher {
	return &cacherFunc{f}
}

type Strict uint
type Options struct {
	// If true then opens DB in read-only mode.
	//
	// The default value is false.
	ReadOnly bool
	// Strict defines the DB strict level
	Strict Strict
	// OpenFileCacheCapacity defines the capacity of the open files caching.
	// Use -1 for zero, this has same effect as specifying NoCacher to OpenFilesCacher.
	//
	// The default value is 200 on MacOS and 500 on other.
	OpenFilesCacheCapacity int
}

// Cacher is caching algorithm.
type Cacher interface {
	New(capacity int) cache.Cacher
}

func (o *Options) GetOpenFileCacher() Cacher {
	if o == nil || o.OpenFilesCacher == 0 {
		return Default
	}
}

func (o *Options) GetReadOnly() bool {
	if o == nil {
		return false
	}
	return o.ReadOnly
}

func (o *Options) GetOpenFilesCacheCapacity() int {
	if o == nil || o.OpenFilesCacheCapacity == 0 {
		return DefaultOpenFilesCacheCapacity
	} else if o.OpenFilesCacheCapacity < 0 {
		return 0
	}
	return o.OpenFilesCacheCapacity
}
